package com.jysz.certificate.service.pm;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.hibernate.sql.JoinFragment;
import org.springframework.stereotype.Service;

import com.jysz.certificate.persistence.dao.pm.UserPerformanceDao;
import com.jysz.certificate.persistence.enums.PostType;
import com.jysz.certificate.persistence.model.pm.AssignUser;
import com.jysz.certificate.persistence.model.pm.UserPerformance;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;

/**
 * @author <a href="mailto:javaengine@outlook.com">Kaca Rich</a>
 *
 */
@Service
public class UserPerformanceService extends EntityService<UserPerformance, Long, UserPerformanceDao>{

	@Resource
	private UserPerformanceDao userPerformanceDao;
	@Resource
	private PAShopMonthDetailService paShopMonthDetailService;
	
	public UserPerformanceDao getEntityDao() {
		return userPerformanceDao;
	}

	public Page<UserPerformance> findPage(UserPerformance search, int currentPage,
			int pageSize, User user, String area, String shopName) {
		Criteria criteria = getEntityDao().createCriteria();
		criteria.addOrder(Order.desc("monthDate"));
		
		if(search != null){
			if(search.getUser() != null){
				Criteria userCriteria = criteria.createCriteria("user");
				if(StringUtils.isNotBlank(search.getUser().getJobNumber())){
					userCriteria.add(Restrictions.like("jobNumber", search.getUser().getJobNumber(), MatchMode.START));
				}
				
				if(StringUtils.isNotBlank(search.getUser().getRealName())){
					userCriteria.add(Restrictions.like("realName", search.getUser().getRealName(), MatchMode.START));
				}
				
				if(search.getUser().getPost() != null){
					userCriteria.add(Restrictions.eq("post", search.getUser().getPost()));
				}
			}
			
			if(StringUtils.isNotBlank(search.getMonthDate())){
				criteria.add(Restrictions.eq("monthDate", search.getMonthDate()));
			}
			
			if(search.getStatus() != null){
				criteria.add(Restrictions.eq("status", search.getStatus()));
			}
		}
		
		if(PostType.Shop.equals(user.getPost())){
			criteria.add(Restrictions.eq("user", user));
		}else if(PostType.Manager.equals(user.getPost())){
//			DetachedCriteria dc = DetachedCriteria.forClass(PAShopMonthDetail.class);
//			
//			dc.setProjection(Projections.projectionList().add(Projections.groupProperty("userPerformance")).add(Projections.property("userPerformance")));
//			
//			DetachedCriteria shopDc = dc.createCriteria("performanceAssignShopDetail").createCriteria("shop");
//			if( StringUtils.isNotBlank(shopName)){
//				shopDc.add(Restrictions.like("shopName", shopName, MatchMode.START));
//			}
//			if(StringUtils.isNotBlank(area)){
//				DetachedCriteria areaDc = shopDc.createCriteria("area");
//				areaDc.add(Restrictions.like("name", area, MatchMode.START));
//			}
			
//			getEntityDao().addShopCriteria(shopDc, true, user);
			//FIXME:没有和人员关联的绩效，区域经理目前没办法查询出来。
			Disjunction disjunction = Restrictions.disjunction();
			DetachedCriteria auDc = DetachedCriteria.forClass(AssignUser.class);
			auDc.setProjection(Projections.projectionList().add(Projections.groupProperty("userPerformance")));
			DetachedCriteria auShopDc = auDc.createCriteria("paShopMonthDetail").createCriteria("performanceAssignShopDetail").createCriteria("shop");
			
			if( StringUtils.isNotBlank(shopName)){
				auShopDc.add(Restrictions.like("shopName", shopName, MatchMode.START));
				
				disjunction.add(Restrictions.like("shop.shopName", shopName, MatchMode.START));
			}
			
			if(StringUtils.isNotBlank(area)){
				DetachedCriteria auAreaDc = auShopDc.createCriteria("area");
				auAreaDc.add(Restrictions.like("name", area, MatchMode.START));
				
				disjunction.add(Restrictions.like("area.name", area, MatchMode.START));
			}
			
			getEntityDao().addShopCriteria(auShopDc, true, user);
			
//			.add(Subqueries.propertyIn("id", dc))
			criteria.add(disjunction.add(Restrictions.eq("user", user)).add(Subqueries.propertyIn("id", auDc)));
		}else{
			
			if(StringUtils.isNotBlank(area) || StringUtils.isNotBlank(shopName)){
//				DetachedCriteria dc = DetachedCriteria.forClass(PAShopMonthDetail.class);
//				dc.setProjection(Projections.projectionList().add(Projections.groupProperty("userPerformance")));
//				
//				DetachedCriteria shopDc = dc.createCriteria("performanceAssignShopDetail").createCriteria("shop");
//				
//				if( StringUtils.isNotBlank(shopName)){
//					shopDc.add(Restrictions.like("shopName", shopName, MatchMode.START));
//				}
//				if(StringUtils.isNotBlank(area)){
//					DetachedCriteria areaDc = shopDc.createCriteria("area");
//					areaDc.add(Restrictions.like("name", area, MatchMode.START));
//				}
			
				//FIXME:区域经理的绩效没办法查询出来。
				
				Disjunction disjunction = Restrictions.disjunction();
				DetachedCriteria auDc = DetachedCriteria.forClass(AssignUser.class);
				auDc.setProjection(Projections.projectionList().add(Projections.groupProperty("userPerformance")));
				DetachedCriteria auShopDc = auDc.createCriteria("paShopMonthDetail").createCriteria("performanceAssignShopDetail").createCriteria("shop");
				
				if( StringUtils.isNotBlank(shopName)){
					auShopDc.add(Restrictions.like("shopName", shopName, MatchMode.START));
					
					criteria.createAlias("shop", "_shop", JoinFragment.LEFT_OUTER_JOIN);
					disjunction.add(Restrictions.like("_shop.shopName", shopName, MatchMode.START));
				}
				if(StringUtils.isNotBlank(area)){
					
					DetachedCriteria auAreaDc = auShopDc.createCriteria("area");
					auAreaDc.add(Restrictions.like("name", area, MatchMode.START));
					
					criteria.createAlias("area", "_area", JoinFragment.LEFT_OUTER_JOIN);
					disjunction.add(Restrictions.like("_area.name", area, MatchMode.START));
				}
				
				//.add(Subqueries.propertyIn("id", dc))
				criteria.add(disjunction.add(Subqueries.propertyIn("id", auDc)));
			}
		}
		
		return this.findPage(criteria, currentPage, pageSize);
	}

}
